/**
 * {作业名称}
 *
 * 输入参数:
 *
 * 输出参数:
 *
 */
(() => {
  // 私有区域

  return function ({ UID, Records }) {
    // 验证输入参数
    if (!UID) throw Error("无效会话");

    // 处理逻辑
    A.db.trans('MP', conn => {
      // 加载组装单明细
      const { Rows } = A.job.CardR(UID, 'ST.组装单明细', ['组装单', '组装单.单号', '组装单.仓库', '品规', '数量'],
        [['组装单', 'in', Records.map(r => r.ID)]]);
      if (Rows.length === 0) throw Error("没有选中的组装单明细");

      // 加载BOM
      const { Rows: bom_rows_all } = A.job.CardR(UID, 'ST.BOM明细', ['主记录', '品规', '品规.商品.名称', '品规.名称', '数量'], {
        Filter: [['主记录', 'in', Rows.map(r => r.品规)]],
      });
      bom_rows_all.forEach(r => {
        bom_rows_all[r.主记录] = bom_rows_all[r.主记录] ?? [];
        bom_rows_all[r.主记录].push(r);
      });
      // 根据BOM还原物料
      Rows.forEach(r => {
        const bom_list = bom_rows_all[r.品规];
        if (!bom_list) throw Error(`品规${r.品规}没有BOM`);
        r.金额 = 0;
        bom_list.forEach(bom => {
          // 加载可用的台账批次
          const { Rows: store_list } = A.job.CardR(UID, 'ST.库存台账', null, {
            Filter: [['仓库', '=', r['组装单.仓库']], ['品规', '=', bom.品规], ['余量', '>', 0]],
            Order: { '生产日期': 'asc', '数量': 'asc' },
          });
          const total = store_list.reduce((acc, cur) => acc + cur.余量, 0);
          if (total < bom.数量 * r.数量) throw Error(`组装仓库中${bom['品规.商品.名称']}规格为'${bom['品规.名称']}'的库存数量不足. 需求${bom.数量 * r.数量}个, 库存${total}个`);

          let waiting = bom.数量 * r.数量;
          const results = [];
          store_list.every(store => {
            if (store.余量 >= waiting) {
              results.push({ ID: store.ID, '生产日期': store.生产日期, '数量': waiting, '单价': store.单价, 金额: waiting * store.单价 });
              waiting = 0;
              return false;
            } else {
              results.push({ ID: store.ID, '生产日期': store.生产日期, '数量': store.余量, '单价': store.单价, 金额: store.余量 * store.单价 });
              waiting -= store.余量;
              return true;
            }
          });
          r.金额 += results.reduce((acc, cur) => acc + cur.金额, 0);
          // 原材料出库
          A.job.CardW(UID, 'ST.库存台账', null, results.map(res => ({
            '仓库': r['组装单.仓库'],
            '品规': bom.品规,
            '生产日期': res.生产日期,
            '数量': 0 - res.数量,
            '余量': 0,
            '单价': res.单价,
            '金额': res.金额,
            '摘要': '组装:' + r['组装单.单号'],
            '上级': res.ID,
          })));
          // 更新余量
          const ids = results.map(res => res.ID);
          A.db.execute('MP', `UPDATE ST_KCTZ A SET A.YL = (SELECT A.SL + SUM(B.SL) FROM (SELECT SJ_ID, SL FROM ST_KCTZ) B WHERE B.SJ_ID=A.ID) WHERE A.ID IN (${ids.map(id => '?').join(',')})`, ids);
        });
      });
      // 组装品入库
      A.job.CardW(UID, 'ST.库存台账', null, Rows.map(r => ({
        '仓库': r['组装单.仓库'],
        '品规': r.品规,
        '生产日期': new Date(),
        '数量': r.数量,
        '余量': r.数量,
        '单价': r.金额 / r.数量,
        '金额': 0 - r.金额,
        '摘要': '组装:' + r['组装单.单号'],
      })));

      // 更新组装单状态
      A.job.CardW(UID, 'ST.组装单', null, Records.map(r => ({
        'ID': r.ID,
        '组装日期': new Date(),
      })));
    });

    // 返回结果
    return true;
  };
})()